package com.springboot.controller;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.springboot.config.security.JwtConfig;
import com.springboot.constant.AdministratorExecl;
import com.springboot.dto.AdminLoginDTO;
import com.springboot.dto.AdministratorDTO;
import com.springboot.dto.EditPasswordDTO;
import com.springboot.entity.Administrator;
import com.springboot.enums.ErrorEnum;
import com.springboot.exception.MyException;
import com.springboot.service.AdministratorService;
import com.springboot.utils.IPUtil;
import com.springboot.utils.Response;
import com.springboot.utils.UserUtil;
import com.springboot.vo.AdminIndexVO;
import com.springboot.vo.AdminLoginVO;
import com.springboot.vo.PageVO;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.RequestEntity;
import org.springframework.http.ResponseEntity;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.util.UriComponentsBuilder;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.io.OutputStream;
import java.net.URI;
import java.net.URLEncoder;

/**
 * @author: lzh
 */
@RestController
public class AdministratorController {

    @Autowired
    AdministratorService administratorService;

    @Autowired
    AuthenticationManager authenticationManager;

    @Autowired
    JwtConfig jwtConfig;

    @Value("${tencent.appid}")
    private String appid;

    @Value("${tencent.secret}")
    private String secret;

    private final String tencentUrl = "https://ssl.captcha.qq.com/ticket/verify";

    /**
     * @param adminLoginDTO :
     * @return : com.springboot.utils.Response
     * @descrition: 后台登录验证
     */
    @GetMapping("/admin/login")
    public Response login(HttpServletRequest request, @Valid AdminLoginDTO adminLoginDTO) {

        //向腾讯防水墙发请求验证
        StringBuilder url = new StringBuilder(tencentUrl);
        url.append("?aid=").append(appid).append("&AppSecretKey=").append(secret).append("&Ticket=")
                .append(adminLoginDTO.getTicket()).append("&Randstr=")
                .append(adminLoginDTO.getRandstr()).append("&UserIP=")
                .append(IPUtil.getClientIp(request));
        System.out.println(url.toString());
        URI uri = UriComponentsBuilder
                .fromUriString(url.toString())
                .build(42);
        RestTemplate restTemplate = new RestTemplate();
        RequestEntity<Void> requestEntity = RequestEntity.get(uri).build();
        ResponseEntity<String> entity = restTemplate.exchange(requestEntity, String.class);
        JSONObject jsonObject = JSON.parseObject(entity.getBody());
        Integer response = jsonObject.getInteger("response");
        if (response != null && response != 1) {
            throw new MyException(14, "腾讯防水墙认证失败：" + jsonObject.getString("err_msg"));
        }

        //验证账号密码
        Authentication authentication = authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(adminLoginDTO.getUsername()
                        , adminLoginDTO.getPassword()));
        SecurityContextHolder.getContext().setAuthentication(authentication);


        AdminLoginVO adminLoginVO = new AdminLoginVO();
        Administrator administrator = UserUtil.getCurrentAdmin();
        //验证通过返回token
        String token = jwtConfig.getToken(administrator.getUsername(), false);
        BeanUtils.copyProperties(administrator, adminLoginVO);
        adminLoginVO.setToken(token);
        return Response.success(adminLoginVO);
    }

    /**
     * @return : com.springboot.utils.Response
     * @descrition: 后台首页
     */
    @GetMapping("/admin/index")
    public Response getIndex() {
        AdminIndexVO index = administratorService.getIndex();
        return Response.success(index);
    }

    /**
     * @param pageNum  :
     * @param pageSize :
     * @param keywords :
     * @return : com.springboot.utils.Response
     * @descrition: 后台获取管理员列表
     */
    @GetMapping("/admin/administrator")
    @PreAuthorize("hasRole('SUPER')")
    public Response getAdminList(@RequestParam(required = false, defaultValue = "1") Integer pageNum,
                                 @RequestParam(required = false, defaultValue = "10") Integer pageSize,
                                 @RequestParam(required = false) String keywords) {
        PageVO pageVO = administratorService.getAdminList(pageNum, pageSize, keywords);
        return Response.success(pageVO);
    }

    /**
     * @param administratorDTO :
     * @return : com.springboot.utils.Response
     * @descrition: 后台添加管理员
     */
    @PostMapping("/admin/administrator")
    @PreAuthorize("hasRole('SUPER')")
    public Response addAdmin(@Valid AdministratorDTO administratorDTO) {
        administratorService.addAdmin(administratorDTO);
        return Response.success();
    }

    /**
     * @param id :
     * @return : com.springboot.utils.Response
     * @descrition: 后台设置超管
     */
    @PutMapping("/admin/administrator")
    @PreAuthorize("hasRole('SUPER')")
    public Response setSuperAdmin(@RequestParam Integer id) {
        administratorService.setSuperAdmin(id);
        return Response.success();
    }

    /**
     * @param id :
     * @return : com.springboot.utils.Response
     * @descrition: 后台删除管理员
     */
    @DeleteMapping("/admin/administrator")
    @PreAuthorize("hasRole('SUPER')")
    public Response deleteAdmin(@RequestParam Integer id) {
        administratorService.deleteAdmin(id);
        return Response.success();
    }

    /**
     * @param response :
     * @return : void
     * @descrition: 管理员列表execl下载
     */
    @GetMapping("/admin/administrator/execl")
    @PreAuthorize("hasRole('SUPER')")
    public void dowloadExecl(HttpServletResponse response) {
        HSSFWorkbook wb = administratorService.dowloadExecl();
        try {
            //设置Http响应头告诉浏览器下载这个附件
            response.setHeader("Content-Disposition"
                    , "attachment;filename=" + URLEncoder.encode(AdministratorExecl.SHEETNAME, "utf-8") + ".xls");
            OutputStream outputStream = response.getOutputStream();
            wb.write(outputStream);
            outputStream.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            throw new MyException(ErrorEnum.DOWLOAD_EXECL_ERROR);
        }
    }

    /**
     * @param editPasswordDTO :
     * @return : com.springboot.utils.Response
     * @descrition: 修改密码
     */
    @PutMapping("/admin/password")
    public Response editPassword(@Valid EditPasswordDTO editPasswordDTO) {
        administratorService.editPassword(editPasswordDTO);
        return Response.success();
    }

}
